#include "StdAfx.h"

#include <boost/foreach.hpp>
#include <regex>
#include "mcsv_file.h"

using namespace std::tr1;

mcsv_file::mcsv_file(void)
{
}

mcsv_file::~mcsv_file(void)
{
}



void mcsv_file::read(const wchar_t* filename)
{
	wifstream infile;
	infile.open(filename,ios::in);
	if( !infile.is_open())
		return ;


	istreambuf_iterator<wchar_t> begin(infile),end;
	wstring text(begin,end);

	
	parse(text);

	infile.close();
}


void mcsv_file::parse(const wstring& text)
{
	wstring::size_type pos = 0;
	wstring::size_type posnext;
	while( (posnext = text.find(L'\n',pos)) != wstring::npos)
	{
		wstring oneline = text.substr(pos,posnext-pos);
		parse_one_line(oneline);
		pos = posnext+1;//²»Òª»»ÐÐ
	}

}

void str_replace_all(wstring& source,wchar_t* find,wchar_t* rep)
{
	wstring::size_type pos = 0;       
	wstring::size_type findlen = wcslen(find);
	wstring::size_type replen = wcslen(rep);
	while((pos = source.find(find,pos)) != wstring::npos)
	{                
		source.replace(pos,findlen,rep);                
		pos += findlen - replen;        
	}
}

void mcsv_file::parse_one_line(const wstring& oneline)
{

	one_line_words lone_line_words;

	const wregex rex(L"([^\",]+)|\"((?:[^\"]|\"\")*)\"");
	wstring::const_iterator oneline_beg = oneline.begin();
	wstring::const_iterator oneline_end = oneline.end();
	wsmatch rmatch;
	while( regex_search(oneline_beg,oneline_end,rmatch,rex))
	{
		if( rmatch.str()[0] == L'"')
		{
			wstring word = rmatch[2].str();
			str_replace_all(word,L"\"\"",L"\"");
//			wcout<<"\n"<<word<<" ";
			lone_line_words.push_back(word);
		}
		else
		{
//			wcout<<"\n"<<rmatch[1].str()<<" ";
			lone_line_words.push_back(rmatch[1].str());
		}
		oneline_beg = rmatch[0].second;
	}
	thelines.push_back(lone_line_words);
}


wstring mcsv_file::get_at(int hang,int lie)
{
	wstring wstr = thelines[hang-1][lie-1];
	return wstr;
}



wostream& operator<<(wostream& os, const mcsv_file& s)
{
	int countline = 0;
	BOOST_FOREACH(mcsv_file::one_line_words olw,s.thelines)
	{
		wcout<<"line:"<<countline+1<<"\n";
		int countword = 0;
		BOOST_FOREACH(wstring word,olw)
		{
			wcout<<"  word "<<countword+1<<": "<<word<<"  ";
			countword++;
		}
		countline++;
		wcout<<"\n";
	}
	return os;
}